/******************************************************************************
 cnome: A C++ source "genes" discover. :-)

 See more details at:

   http://www.codeplex.com/cnome

 The original author site is at: http://www.alemosbarbosa.com/

 Copyright (c) 2008-2010 Alexandre Lemos Barbosa.
 Distributed under the MIT License. (See accompanying file LICENSE-MIT.txt 
 or at http://www.codeplex.com/cnome/license)
 ******************************************************************************/

#ifndef EXCEPTION_HANDLING_H
#define EXCEPTION_HANDLING_H

#include "actions.h"
#include "cnome.h"
#include "directives.h"
#include "tokens.h"

namespace cnome {
template <typename ScannerT>
void
cpp::definition<ScannerT>::exception_handling(cpp const& self)
    {
        using namespace actions;
        using namespace directive;
        using namespace util;

        try_block =
            TRY >> compound_statement >> handle_seq
        ;

        function_try_block =
            TRY >> !ctor_initializer >> function_body >> handle_seq
        ;

        handle_seq =
            handle >> !handle_seq
        ;

        handle = 
            CATCH >> LEFTPAREN >> exception_declaration >> RIGHTPAREN >> compound_statement
        ;

        exception_declaration =
            ( type_specifier_seq >> declarator )          |
            ( type_specifier_seq >> abstract_declarator ) |
            type_specifier_seq                            |
            ELLIPSIS
        ;

        throw_expression =
            THROW >> !assignment_expression
        ;

        type_id_list =
            sss_d[ type_id ] >> type_id_list_helper
        ;

        type_id_list_helper =
            ( COMMA >> sss_d[ type_id ] >> type_id_list_helper ) |
            EPSILON
        ;
        exception_specification =
            THROW >> LEFTPAREN >> !type_id_list >> RIGHTPAREN
        ;

        type_id_list =
            sss_d[ type_id ] >> type_id_list_helper
        ;

        type_id_list_helper =
            ( COMMA >> sss_d[ type_id ] >> type_id_list_helper ) |
            EPSILON
        ;
        //  End grammar definition
          
        // turn on the debugging info.
        BOOST_SPIRIT_DEBUG_RULE(try_block);
        BOOST_SPIRIT_DEBUG_RULE(compound_statement);
        BOOST_SPIRIT_DEBUG_RULE(handle_seq);
        BOOST_SPIRIT_DEBUG_RULE(function_try_block);
        BOOST_SPIRIT_DEBUG_RULE(ctor_initializer);
        BOOST_SPIRIT_DEBUG_RULE(function_body);
        BOOST_SPIRIT_DEBUG_RULE(handle_seq);
        BOOST_SPIRIT_DEBUG_RULE(handle_seq);
        BOOST_SPIRIT_DEBUG_RULE(handle);
        BOOST_SPIRIT_DEBUG_RULE(exception_declaration);
        BOOST_SPIRIT_DEBUG_RULE(compound_statement);
        BOOST_SPIRIT_DEBUG_RULE(type_specifier_seq);
        BOOST_SPIRIT_DEBUG_RULE(declarator); 
        BOOST_SPIRIT_DEBUG_RULE(abstract_declarator); 
        BOOST_SPIRIT_DEBUG_RULE(throw_expression);
        BOOST_SPIRIT_DEBUG_RULE(assignment_expression);
        BOOST_SPIRIT_DEBUG_RULE(type_id_list);
        BOOST_SPIRIT_DEBUG_RULE(type_id_list_helper);
        BOOST_SPIRIT_DEBUG_RULE(type_id);
        BOOST_SPIRIT_DEBUG_RULE(exception_specification);

        BOOST_SPIRIT_DEBUG_RULE(TRY);
        BOOST_SPIRIT_DEBUG_RULE(THROW);
        BOOST_SPIRIT_DEBUG_RULE(CATCH);
        BOOST_SPIRIT_DEBUG_RULE(LEFTPAREN);
        BOOST_SPIRIT_DEBUG_RULE(RIGHTPAREN);
        BOOST_SPIRIT_DEBUG_RULE(ELLIPSIS);
        BOOST_SPIRIT_DEBUG_RULE(COMMA);
        BOOST_SPIRIT_DEBUG_RULE(EPSILON);
        BOOST_SPIRIT_DEBUG_RULE(LEFTPAREN);
        BOOST_SPIRIT_DEBUG_RULE(RIGHTPAREN);
        BOOST_SPIRIT_DEBUG_RULE(COMMA);
        BOOST_SPIRIT_DEBUG_RULE(EPSILON);
    }
}  // namespace cnome

#endif // EXCEPTION_HANDLING_H
